<template>
  <div v-click-calendar>
    <input type="text" :value="formatDate" />
    <div class="pannel" v-if="isVisible">
      <Header class="pannel-nav">
        <span>&lt;</span>
        <span>&lt;&lt;</span>
        <span @click="selectYear" >{{getYear}}年</span>
        <span @click="selectMonth">{{this.months[getMonth.month]}}月</span>
        <span>&gt;&gt;</span>
        <span>&gt;</span>
      </Header>
      <div class="pannel-content">
          <div class="selectYearOrMonth" v-show="!isSelectDay">
              <span 
                class="block" 
                v-for="k in 12" 
                :key="'m' + k"
                @click="selectDay(k-1)"
              >
                {{ isSelectYear? years[k-1] : months[k-1]+'月' }}
              </span>
          </div>
        <div class="selectDay" v-show="isSelectDay" >
          <div>
            <span class="cell" v-for="j in 7" :key="'week-' + j">{{week[j-1]}}</span>
          </div>
          <div v-for=" i in 6" :key="i">
            <span
              class="cell day"
              :class="{
                notCurrentMonth: !isCurrentMonth(visibleDays[(i-1)*7 + (j-1)]),
                currentDay: isCurrentDay(visibleDays[(i-1)*7 + (j-1)])
              }"
              @click="getDate(visibleDays[(i-1)*7 + (j-1)])"
              v-for=" j in 7"
              :key="j"
            >
                {{visibleDays[(i-1)*7 + (j-1)].getDate()}}
            </span>
          </div>
        </div>
      </div>
      <Footer class="pannel-footer">
        <button @click="today">今天</button>
      </Footer>
    </div>
  </div>
</template>

<script>
import * as utils from '../utils/initDate.js'
export default {
    directives: {
        clickCalendar: {
                // 绑定指令
            bind(el, binding, vnode){
                let handler = (e) => {
                    if(el.contains(e.target)){
                        // 判断当前面板是否显示出来了
                        if(!vnode.context.isVisible){ 
                            vnode.context.focus();
                        }
                    }else{
                        // 若指令绑定的el内部的子dom使用了v-if，动态渲染出来的不属于el的子dom！注意！
                        if(vnode.context.isVisible){ 
                            vnode.context.blur();
                            vnode.context.initPannel();
                        }
                    }
                }
                el.handler = handler;
                document.addEventListener('click', el.handler );
            },
                // 解除绑定指令
            unbind(el, binding, vnode) {
                document.addEventListener('click', el.handler );
            }
        }
    },
    props: {
        value: {
            type: Date,
            default: () => new Date()
        }
    },
    computed: {
        formatDate() {
            let { year,month,day} = utils.getYearMonthDay(this.value);
            return year + '-' + (month+1) + '-' + day;
        },
        visibleDays() {
            // 取当前是周几
            let {year,month} = utils.getYearMonthDay(this.value);
                // 获取月份第一天
            let currentFirstDay = utils.getFirstDay(year,month,1);
                // 把天数往前移动几天
            let week = currentFirstDay.getDay();
                // 循环42天
            let startDay = currentFirstDay - week * 60 * 60 * 1000 * 24;
            let arr = [];
            for( let i = 0; i < 42; i++ ){
                arr.push(new Date(startDay + i * 60 * 60 * 1000 * 24))
            }
            return arr;
        },
        // 获取value值的年份
        getYear() {
            let {year} = utils.getYearMonthDay(this.value);
            return year;
        },
        // 获取value值的月份
        getMonth() {
            let {year,month} = utils.getYearMonthDay(this.value);
            return {year,month};
        },
        // 计算年面板上显示的年份
        years(){
            return new Array(12).fill(null).map((item,index,arr)=>{
                return arr[index] = this.getYear - 6 + index;
            })
        }
    },
    methods: {
        focus(el) {
            this.isVisible = true;
            console.log('获得焦点');
        },
        blur(el) {
            this.isVisible = false;
            console.log('失去焦点');
        },
        // 获取日期，并且修改value值
        getDate(date) {
            this.time = new Date(date);
            this.$emit('change', date);
            this.$emit('input', date); 
            this.isVisible = false;
        },
        // 判断日期是否属于当前月份
        isCurrentMonth(date) {
            let currentDate = utils.getYearMonthDay(this.value);
            let {year, month} = utils.getYearMonthDay(date);
            if(currentDate.year == year && currentDate.month == month){
                return true;
            }else {
                return false;
            }
        },
        // 判断是否为当前日期
        isCurrentDay(date) {
            let {month, day} = utils.getYearMonthDay(date);
            let {month:m,day:d} = utils.getYearMonthDay(new Date());
            if(month == m && day == d){
                return true;
            }else{
                return false;
            }
        },
        // 开启年面板
        selectYear() {
            this.isSelectDay = false;
            this.isSelectYear = true;
        },
        // 开启月面板
        selectMonth() {
            this.isSelectDay = false;
            this.isSelectYear = false;
        },
        // 用于点击月份或年份，并将时间值值绑定到input的value上
        selectDay(index) {
            if(this.isSelectYear){
                this.$emit('input', new Date(this.years[index], 0, 1));
            }else{
                let {year} = utils.getYearMonthDay(this.value);
                this.$emit('input', new Date(year, index, 1));
            }
            this.isSelectDay = true;
        },
        // 获取今天的日期
        today(){
            this.$emit('input', new Date());
        },
        // 初始化日期面板
        initPannel() {
            this.isSelectYear = false;
            this.isSelectDay = true;
        }
    },
    data() {
        return {
            time: null,
            isSelectYear: false,
            isSelectDay: true,
            isVisible: false,
            selectDate: null,
            week: ['日','一','二','三','四','五','六'],
            months: ['一','二','三','四','五','六','七','八','九','十','十一','十二']
        }
    },
    mounted() {
        console.log(this.years)
    }
}
</script>

<style>
.pannel {
  width: 224px;
  height: 256px;
  position: absolute;
  background-color: white;
  box-shadow: 2px 2px 2px black;
  border: 1px solid black;
}
.pannel .pannel-nav {
  display: flex;
  justify-content: space-around;
  height: 30px;
}
.pannel .pannel-nav span {
  cursor: pointer;
  user-select: none;
}
.pannel .pannel-content {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
.pannel .pannel-content .block {
  display: inline-flex;
  justify-content: center;
  align-items: center;
  width: 112px;
  height: 37.5px;
  border-radius: 3px;
}
.pannel .pannel-content .cell {
  display: inline-flex;
  justify-content: center;
  align-items: center;
  width: 32px;
  height: 32px;
  border-radius: 3px;
}
.pannel .pannel-content .block:hover,.pannel .pannel-content .day:hover {
  background-color: rgb(0, 129, 204);
  color: white;
  cursor: pointer;
}
.pannel .pannel-footer {
  margin-top: 5px;
}
.notCurrentMonth {
  color: silver;
}
.currentDay {
  background-color: red;
}
</style>